'''
Created on 07/04/2009

@author: Edward
'''

from xml.etree import ElementTree
from yarra import helper
from yarra.datastore import dsconstants, dsofactory
from yarra.datastore.dso import DSO
from yarra.datastore.dst import DST
from yarra.event import eventconstants
from yarra.event.event import Event
from yarra.event.eventhandler import BaseEventHandler
from yarra.event.eventmanager import EventManager
from yarra.handler import messagetypeconstants
import datetime
import httplib
import os
import re

class PublicApplicationStatusHTTPRequestHandler(BaseEventHandler):
    '''
    classdocs
    '''

    def __init__(self):
        '''
        Constructor
        '''
    # Given the numeric portion of the SPEAR reference number, calculate the check character.
    def calculate_spear_reference(self, num):
            total = 0
            mult = 7
            for n in num:
                    total += int(n) * mult
                    mult -= 1
            return 'AVTSPMJHECBA'[total % 11]
    
    # Validate the format (Snnnnnnx) and check character of a SPEAR reference number.
    def check_spear_reference(self, ref):
        match = re.match('^S(\d{6})([ABCEHJMPSTV]{1})$', ref)
        if match is not None:
                if self.calculate_spear_reference(match.group(1)) == match.group(2):
                        return True
        return False
    
    def do(self, data):
        dso = data
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()
        lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_LOCK).get_literal()
        spear_reference_dst = dso.get_dst(subject=dsconstants.SUBJECT_FORM_DATA,
                    predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER) 

        if spear_reference_dst and self.check_spear_reference(spear_reference_dst.get_literal()):
            dst1 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_TYPE, 
                      literal=messagetypeconstants.PUBLIC_APPLICATION_STATUS_TEST_REQUEST_MESSAGE_TYPE)
            dst2 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_DESTINATION_NODE, 
                      literal="node_spear")
            dst3 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_CONTENT, 
                      object=dsconstants.SUBJECT_MESSAGE_CONTENT)
            dst4 = DST(subject=dsconstants.SUBJECT_MESSAGE_CONTENT, 
                      predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER, 
                      literal=spear_reference_dst.get_literal())
            dst5 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_HTTP_REQUEST, 
                      literal=http_request)       
            dst6 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_LOCK, 
                      literal=lock)
            new_dso = DSO([dst1, dst2, dst3, dst4, dst5, dst6])
            event = Event(eventconstants.SEND_TO_HUB_EVENT_TYPE, new_dso)
            EventManager().add_event(event)
        else:
            relative_path = "../../../pages/im/imerror.html"
            
            fault_message = "invalid-spear-reference"
            # get the html template
            template_path = os.path.join(os.path.dirname(__file__), relative_path)
            file = open(template_path)
            html_template_string = file.read()
            html_string = html_template_string.replace('${fault_message}', fault_message)
            new_dso = dsofactory.create_dso_for_im_http_response_handler(httplib.OK, 
                                                                   'text/html', 
                                                                   html_string, 
                                                                   http_request, 
                                                                   lock)
            event = Event(eventconstants.HTTP_RESPONSE_EVENT_TYPE, new_dso)
            EventManager().add_event(event)

class PublicApplicationStatusWebServiceRequestHandler(BaseEventHandler):
    
    def do(self, data):
        dso = data

        spear_reference_number_dst = dso.get_dst(subject=dsconstants.SUBJECT_MESSAGE_CONTENT,
                                 predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER)
        spear_reference_number = spear_reference_number_dst.get_literal()
                
        # create web service name dst
        web_service_name_dst = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_SPEAR_A2A_WEB_SERVICE_NAME,
            literal='LxSpearApplication_2_0')
        
        # create soap message
        access_token = helper.get_access_token()
        env = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body = ElementTree.SubElement(env, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        getapp = ElementTree.SubElement(body, '{http://test.webservice.spear.lx.dse.vic.gov.au}getApplication')
        getapp.append(access_token)
        ref = ElementTree.SubElement(getapp,
            '{http://test.webservice.spear.lx.dse.vic.gov.au}spearRef')
        ref.text = spear_reference_number      
        soap = '<?xml version="1.0" encoding="utf-8" ?>\r\n' + ElementTree.tostring(env)        
        
        soap_message_dst = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_SOAP_MESSAGE,
            literal=soap)        
        
        web_service_response_event_type_dst = DST(subject=dsconstants.SUBJECT_ROOT, 
            predicate=dsconstants.PREDICATE_WEB_SERVICE_RESPONSE_EVENT_TYPE,
            literal=eventconstants.PUBLIC_APPLICATION_STATUS_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE)
        
        # update dso
        dso.add_dst(soap_message_dst)
        dso.add_dst(web_service_name_dst)
        dso.add_dst(web_service_response_event_type_dst)
        event = Event(type=eventconstants.SEND_TO_SPEAR_EVENT_TYPE, data=dso)
        EventManager().add_event(event)